/*
 *------------------------------------------------------------------------------
 * @File      :    ov2710_dvp.c
 * @Date      :    2021-3-20
 * @Author    :    lomboswer <lomboswer@lombotech.com>
 * @Brief     :    Source file for MDP(Media Development Platform).
 *
 * Copyright (C) 2020-2021, LomboTech Co.Ltd. All rights reserved.
 *------------------------------------------------------------------------------
 */
#include "ei_comm_camera.h"
#include "camera_usr.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

#define SNS_ID 2710
#define SNS_NAME  "ov2710_dvp"
#define DEV_TYPE DVP

static SNS_STATE_S g_sastSns[VISS_MAX_DEV_NUM];

static const SNS_REG_S s_aRaw1920x1080[] = {
    {0x3103, 0x93 },
    {0x3008, 0x82 },
    {0x3017, 0x7f },
    {0x3018, 0xfc },
    {0x3706, 0x61 },
    {0x3712, 0x0c },
    {0x3630, 0x6d },
    {0x3801, 0xb4 },
    {0x3621, 0x04 },
    {0x3604, 0x60 },
    {0x3603, 0xa7 },
    {0x3631, 0x26 },
    {0x3600, 0x04 },
    {0x3620, 0x37 },
    {0x3623, 0x00 },
    {0x3702, 0x9e },
    {0x3703, 0x5c },
    {0x3704, 0x40 },
    {0x370d, 0x0f },
    {0x3713, 0x9f },
    {0x3714, 0x4c },
    {0x3710, 0x9e },
    {0x3801, 0xc4 },
    {0x3605, 0x05 },
    {0x3606, 0x3f },
    {0x302d, 0x90 },
    {0x370b, 0x40 },
    {0x3716, 0x31 },
    {0x3707, 0x52 },
    {0x380d, 0x74 },
    {0x5181, 0x20 },
    {0x518f, 0x00 },
    {0x4301, 0xff },
    {0x4303, 0x00 },
    {0x3a00, 0x78 },
    {0x300f, 0x88 },
    {0x3011, 0x28 },
    {0x3a1a, 0x06 },
    {0x3a18, 0x00 },
    {0x3a19, 0xe0 },
    {0x3a13, 0x50 },
    {0x382e, 0x0f },
    {0x381a, 0x1a },
    {0x401d, 0x02 },
    {0x5688, 0x03 },
    {0x5684, 0x07 },
    {0x5685, 0xa0 },
    {0x5686, 0x14 },
    {0x5687, 0x43 },
    {0x3a0f, 0xf0 },
    {0x3a10, 0x38 },
    {0x3a1b, 0xf8 },
    {0x3a1e, 0x30 },
    {0x3a11, 0x90 },
    {0x3a1f, 0x10 },
    {0x3010, 0x10 },
    {0x3012, 0x01 },//isp 0x05, dma 0x01
    {0x3503, 0x07 },
    {0x3502, 0x00 },
    {0x3501, 0x22 },
    {0x3500, 0x00 },
    {0x350b, 0x00 },
    {0x350a, 0x00 },
    {0x3406, 0x01 },
    {0x3400, 0x04 },
    {0x3401, 0x00 },
    {0x3402, 0x04 },
    {0x3403, 0x00 },
    {0x3404, 0x04 },
    {0x3405, 0x00 },
    {0x4000, 0x05 },
    {0x302c, 0x00 },
    {0x5000, 0xdf },
};

static const SNS_REG_S s_aRaw1280x720[] = {
    { 0x3008, 0x42 },
    { 0x300e, 0x1a },
    { 0x300f, 0x88 },
    { 0x3010, 0x00 },
    { 0x3011, 0x18 },
    { 0x3012, 0x00 },
    { 0x3016, 0x00 },
    { 0x3017, 0x7f },
    { 0x3018, 0xfc },
    { 0x3019, 0x00 },
    { 0x301a, 0x00 },
    { 0x301b, 0x00 },
    { 0x301c, 0x00 },
    { 0x301d, 0x00 },
    { 0x301e, 0x00 },
    { 0x302c, 0x02 },
    { 0x3100, 0x6c },
    { 0x3103, 0x03 },
    { 0x3104, 0x01 },
    { 0x3200, 0x40 },
    { 0x3201, 0x4a },
    { 0x3202, 0x54 },
    { 0x3203, 0x5e },
    { 0x3212, 0x10 },
    { 0x3621, 0x04 },
    { 0x370d, 0x07 },
    { 0x3800, 0x01 },
    { 0x3801, 0xc4 },
    { 0x3802, 0x00 },
    { 0x3803, 0x0a },
    { 0x3804, 0x07 },
    { 0x3805, 0x80 },
    { 0x3806, 0x04 },
    { 0x3807, 0x38 },
    { 0x3808, 0x07 },
    { 0x3809, 0x80 },
    { 0x380a, 0x04 },
    { 0x380b, 0x38 },
    { 0x380c, 0x09 },
    { 0x380d, 0x74 },
    { 0x380e, 0x04 },
    { 0x380f, 0x50 },
    { 0x3810, 0x10 },
    { 0x3818, 0x80 },
    { 0x3500, 0x00 },
    { 0x3501, 0x33 },
    { 0x3502, 0x80 },
    { 0x3503, 0x07 },
    { 0x350a, 0x00 },
    { 0x350b, 0x00 },
    { 0x350c, 0x00 },
    { 0x350d, 0x00 },
    { 0x3a00, 0x78 },
    { 0x3a01, 0x04 },
    { 0x3a02, 0x02 },
    { 0x3a03, 0x28 },
    { 0x3a04, 0x00 },
    { 0x3a08, 0x14 },
    { 0x3a09, 0xc0 },
    { 0x3a0a, 0x11 },
    { 0x3a0b, 0x40 },
    { 0x3a0d, 0x04 },
    { 0x3a0e, 0x03 },
    { 0x3a0f, 0x40 },
    { 0x3a10, 0x38 },
    { 0x3a11, 0x90 },
    { 0x3a12, 0x00 },
    { 0x3a13, 0x54 },
    { 0x3a14, 0x01 },
    { 0x3a15, 0xf2 },
    { 0x3a16, 0x00 },
    { 0x3a17, 0x89 },
    { 0x3a18, 0x00 },
    { 0x3a19, 0x7a },
    { 0x3a1b, 0x48 },
    { 0x3a1c, 0x06 },
    { 0x3a1d, 0x18 },
    { 0x3a1e, 0x30 },
    { 0x3a1f, 0x10 },
    { 0x3a20, 0x20 },
    { 0x3d00, 0x00 },
    { 0x3d01, 0x00 },
    { 0x3d02, 0x00 },
    { 0x3d03, 0x00 },
    { 0x3d04, 0x00 },
    { 0x3d05, 0x00 },
    { 0x3d06, 0x00 },
    { 0x3d07, 0x00 },
    { 0x3d08, 0x00 },
    { 0x3d09, 0x00 },
    { 0x3d0a, 0x00 },
    { 0x3d0b, 0x00 },
    { 0x3d0c, 0x00 },
    { 0x3d0d, 0x00 },
    { 0x3d0e, 0x00 },
    { 0x3d0f, 0x00 },
    { 0x3d10, 0x00 },
    { 0x4000, 0x01 },
    { 0x4001, 0x00 },
    { 0x4002, 0x00 },
    { 0x401d, 0x22 },
    { 0x4201, 0x00 },
    { 0x4202, 0x00 },
    { 0x4700, 0x04 },
    { 0x4704, 0x00 },
    { 0x4708, 0x01 },
    { 0x4709, 0x00 },
    { 0x4800, 0x04 },
    { 0x4801, 0x03 },
    { 0x4803, 0x50 },
    { 0x4804, 0x8d },
    { 0x4805, 0x10 },
    { 0x4810, 0xff },
    { 0x4811, 0xff },
    { 0x4812, 0x00 },
    { 0x4813, 0x00 },
    { 0x4814, 0x2a },
    { 0x4815, 0x00 },
    { 0x4818, 0x00 },
    { 0x4819, 0x96 },
    { 0x481a, 0x00 },
    { 0x481b, 0x3c },
    { 0x481c, 0x01 },
    { 0x481d, 0x86 },
    { 0x481e, 0x00 },
    { 0x481f, 0x3c },
    { 0x4820, 0x00 },
    { 0x4821, 0x56 },
    { 0x4822, 0x00 },
    { 0x4823, 0x3c },
    { 0x4824, 0x00 },
    { 0x4825, 0x32 },
    { 0x4826, 0x00 },
    { 0x4827, 0x32 },
    { 0x4828, 0x00 },
    { 0x4829, 0x64 },
    { 0x482a, 0x05 },
    { 0x482b, 0x04 },
    { 0x482c, 0x00 },
    { 0x482d, 0x00 },
    { 0x482e, 0x34 },
    { 0x482f, 0x00 },
    { 0x4830, 0x00 },
    { 0x4831, 0x04 },
    { 0x4832, 0x00 },
    { 0x5000, 0x59 },
    { 0x5001, 0x4e },
    { 0x5002, 0xe0 },
    { 0x5005, 0xdc },
    { 0x501f, 0x03 },
    { 0x503d, 0x00 },
    { 0x3400, 0x04 },
    { 0x3401, 0x00 },
    { 0x3402, 0x04 },
    { 0x3403, 0x00 },
    { 0x3404, 0x04 },
    { 0x3405, 0x00 },
    { 0x3406, 0x00 },
    { 0x5180, 0x40 },
    { 0x5181, 0x20 },
    { 0x5182, 0x04 },
    { 0x5183, 0x08 },
    { 0x518c, 0xf0 },
    { 0x518d, 0xf0 },
    { 0x518e, 0xf0 },
    { 0x518f, 0x00 },
    { 0x5680, 0x00 },
    { 0x5681, 0x00 },
    { 0x5682, 0x00 },
    { 0x5683, 0x00 },
    { 0x5684, 0x07 },
    { 0x5685, 0xa0 },
    { 0x5686, 0x04 },
    { 0x5687, 0x43 },
    { 0x5780, 0x7f },
    { 0x5781, 0x20 },
    { 0x5782, 0x18 },
    { 0x5783, 0x08 },
    { 0x5784, 0x04 },
    { 0x5785, 0x40 },
    { 0x5786, 0x18 },
    { 0x5787, 0x08 },
    { 0x5788, 0x04 },
    { 0x5789, 0x08 },
    { 0x578a, 0x20 },
    { 0x578b, 0x07 },
    { 0x578c, 0x00 },
    { 0x5790, 0x00 },
    { 0x5791, 0x08 },
    { 0x5792, 0x00 },
    { 0x5793, 0x18 },
    { 0x5794, 0x00 },
    { 0x5795, 0x80 },
    { 0x5796, 0x01 },
    { 0x5797, 0x00 },
    { 0x5800, 0x03 },
    { 0x5801, 0x0c },
    { 0x5802, 0x03 },
    { 0x5803, 0x06 },
    { 0x5804, 0x22 },
    { 0x5805, 0x07 },
    { 0x5806, 0xc2 },
    { 0x5807, 0x08 },
    { 0x5808, 0x03 },
    { 0x5809, 0x0c },
    { 0x580a, 0x03 },
    { 0x580b, 0x06 },
    { 0x580c, 0x22 },
    { 0x580d, 0x07 },
    { 0x580e, 0xc2 },
    { 0x580f, 0x08 },
    { 0x5810, 0x03 },
    { 0x5811, 0x0c },
    { 0x5812, 0x03 },
    { 0x5813, 0x06 },
    { 0x5814, 0x22 },
    { 0x5815, 0x07 },
    { 0x5816, 0xc2 },
    { 0x5817, 0x08 },
    { 0x5818, 0x04 },
    { 0x5819, 0x80 },
    { 0x581a, 0x06 },
    { 0x581b, 0x0c },
    { 0x581c, 0x80 },
    { 0x6000, 0x1f },
    { 0x6001, 0x01 },
    { 0x6002, 0x00 },
    { 0x6003, 0x76 },
    { 0x6004, 0x42 },
    { 0x6005, 0x01 },
    { 0x6006, 0x00 },
    { 0x6007, 0x76 },
    { 0x6008, 0x42 },
    { 0x6009, 0x01 },
    { 0x600a, 0x00 },
    { 0x600b, 0x76 },
    { 0x600c, 0x42 },
    { 0x600d, 0x01 },
    { 0x600e, 0x00 },
    { 0x600f, 0x76 },
    { 0x6010, 0x42 },
    { 0x6011, 0x01 },
    { 0x6012, 0x00 },
    { 0x6013, 0x76 },
    { 0x6014, 0x42 },
    { 0x302d, 0x90 },
    { 0x3600, 0x04 },
    { 0x3601, 0x04 },
    { 0x3602, 0x04 },
    { 0x3603, 0xa7 },
    { 0x3604, 0x60 },
    { 0x3605, 0x05 },
    { 0x3606, 0x12 },
    { 0x3620, 0x07 },
    { 0x3623, 0x40 },
    { 0x3630, 0x6b },
    { 0x3631, 0x24 },
    { 0x3a1a, 0x06 },
    { 0x3702, 0x9e },
    { 0x3703, 0x74 },
    { 0x3704, 0x10 },
    { 0x3706, 0x61 },
    { 0x370b, 0x40 },
    { 0x3710, 0x9e },
    { 0x3712, 0x0c },
    { 0x3713, 0x8b },
    { 0x3714, 0x74 },
    { 0x3811, 0x06 },
    { 0x381c, 0x21 },
    { 0x381d, 0x50 },
    { 0x381e, 0x01 },
    { 0x381f, 0x20 },
    { 0x3820, 0x00 },
    { 0x3821, 0x00 },
    { 0x401c, 0x08 },
    { 0x4301, 0xff },
    { 0x4303, 0x00 },
    { 0x5688, 0x03 },
    { 0x3500, 0x00 },
    { 0x3501, 0x4c },
    { 0x3502, 0x0c },
    { 0x350a, 0x00 },
    { 0x350b, 0x05 },
};

static CAMERA_POWER_ACT_S s_stPowerUpAct[] = {
    {SNS_RESET, SNS_DOWN},
    {SNS_DELAY, 5},
    {SNS_PWDN,  SNS_UP},
    {SNS_DELAY, 10},
    {SNS_PWDN,  SNS_DOWN},
    {SNS_DELAY, 5},
    {SNS_RESET, SNS_UP},
    {SNS_DELAY, 10},
};

static CAMERA_POWER_ACT_S s_sPowerDownAct[] = {
    {SNS_RESET, SNS_DOWN},
    {SNS_DELAY, 10},
    {SNS_PWDN,  SNS_UP},
};

static SNS_TYPE_ATTR_S s_astSnsAttr[] = {
    {
        .enSnsType          = OV2710_DVP_1280_720_30FPS_RAW10,
        .enPixelFormat      = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq           = VISS_RGB_SEQ_GRBG,
        .stSize             = {1280, 720},
        .u32Mclock          = 24000000,

        .u32Left            = 0,
        .u32Top             = 0,
        .u32Vts             = 1104,
        .u32Hts             = 2420,
        .u32Pclk            = 80150400,

        .u32FrameRate        = 30,
        .astRegCfgs[0].pstRegs      = s_aRaw1280x720,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw1280x720),
    },
    {
        .enSnsType          = OV2710_DVP_1920_1080_15FPS_RAW10,
        .enPixelFormat      = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq           = VISS_RGB_SEQ_GRBG,
        .stSize             = {1920, 1080},
        .u32Mclock          = 24000000,

        .u32Left            = 0,
        .u32Top             = 0,
        .u32Vts             = 1104,
        .u32Hts             = 2420,
        .u32Pclk            = 40075200,

        .u32FrameRate        = 15,
        .astRegCfgs[0].pstRegs      = s_aRaw1920x1080,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw1920x1080),
    },
};

static int CAMERA_SetI2cInfo(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    if (pstSnsState->stI2cInfo.fd > 0) {
        return EI_SUCCESS;
    }

    pstSnsState->stI2cInfo.u8RegBits = 16;
    pstSnsState->stI2cInfo.u8ValBits = 8;
#if defined(CONFIG_ARCH_LOMBO_N7V7)
    pstSnsState->stI2cInfo.u16I2cBusNum = 3;
#else
    pstSnsState->stI2cInfo.u16I2cBusNum = 4;
#endif
    pstSnsState->stI2cInfo.u16I2cDevAddr = 0x36;
    pstSnsState->pcName = SNS_NAME;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_Detect(VISS_DEV VissDev)
{
    EI_U8 u8Tmp[2];
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U16 u16Id;
    SNS_STATE_S *pstSnsState = EI_NULL;
    I2C_INFO_S *pstI2cInfo = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;

    CAMERA_CHECK_POINTER(pstI2cInfo->pfnReadReg);
    s32Ret = pstI2cInfo->pfnReadReg(pstSnsState, 0x300A, &u8Tmp[0]);
    if (s32Ret != 0) {
        PRT_VISS_ERR("tmp[0]=%x\n", u8Tmp[0]);
        return s32Ret;
    }
    s32Ret = pstI2cInfo->pfnReadReg(pstSnsState, 0x300B, &u8Tmp[1]);
    if (s32Ret != 0) {
        PRT_VISS_ERR("tmp[0]=%x,tmp[1]=%x\n", u8Tmp[0], u8Tmp[1]);
        return s32Ret;
    }
    u16Id = (u8Tmp[0] << 8) | u8Tmp[1];
    PRT_VISS_INFO("OV2710 id: 0x%04x.\n", u16Id);

    if (u16Id != 0x2710) {
        PRT_VISS_ERR("OV2710 ID wrong! (0x%04x != 0x2710)\n", u16Id);
        return EI_FAILURE;
    }

    return EI_SUCCESS;
}

/* The following functions can be modified as needed */

static int CAMERA_I2cInit(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    int ret = EI_SUCCESS;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    ret = CAMERA_SetI2cInfo(dev);
    CAMERA_CHECK_SUCCESS(ret);

    ret = CAMERA_I2C_Reg_Ops(&pstSnsState->stI2cInfo);
    CAMERA_CHECK_SUCCESS(ret);

    return EI_SUCCESS;
}

static int CAMERA_I2cExit(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_PowerUp(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    MI_VISS_SnsPower(VissDev, 0xA0000000);

    CAMERA_SensorPowerUp(VissDev, pstSnsState);

    return 0;
}

static EI_S32 CAMERA_PowerDown(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    MI_VISS_SnsPower(VissDev, 0x00000000);

    CAMERA_SensorPowerDown(VissDev, pstSnsState);

    return 0;
}

static EI_S32 CAMERA_Init(VISS_DEV dev)
{
    EI_U32 j;
    const SNS_TYPE_ATTR_S *pstSnsType;
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstSnsType = pstSnsState->pstSnsAttr;
    for (j = 0; j < MAX_COF; j++) {
        s32Ret = pstSnsState->stI2cInfo.pfnwriteRegList(pstSnsState,
                pstSnsType->astRegCfgs[j].pstRegs, pstSnsType->astRegCfgs[j].u32RegsCnt);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("%s writeRegList err", SNS_NAME);
            return s32Ret;
        }
    }

    PRT_VISS_INFO("%s writeRegList success", SNS_NAME);

    return s32Ret;
}

static void CAMERA_Exit(VISS_DEV dev)
{
    CAMERA_I2cExit(dev);

    return;
}

static EI_S32 CAMERA_Stream(VISS_DEV dev, EI_BOOL bOn)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);
    PRT_VISS_ERR("%s CAMERA_Stream*******%d\n", SNS_NAME, bOn);

    if (bOn) {
        s32Ret = pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3008, 0x02);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("CAMERA_Stream*******%d\n", bOn);
        }
    } else {
        s32Ret = pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3008, 0x42);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("CAMERA_Stream*******%d\n", bOn);
        }
    }
    return s32Ret;

}

static EI_S32 CAMERA_SetImageMode(VISS_DEV dev, SNS_TYPE_E enSnsType)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstSnsState->enSnsType = enSnsType;
    pstSnsState->bSyncInit = EI_FALSE;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_EnumSnstype(VISS_DEV VissDev, EI_U32 u32Index, SNS_TYPE_E *peSnstype)
{
    const SNS_TYPE_ATTR_S *pstSnsType;

    if (u32Index >= ARRAY_SIZE(s_astSnsAttr))
        return EN_ERR_NO_FOUND;

    pstSnsType = &s_astSnsAttr[u32Index];

    *peSnstype = pstSnsType->enSnsType;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_InitSensorExpFunction(SENSOR_EXP_FUNC_S *pstSensorExpFunc)
{
    CAMERA_CHECK_POINTER(pstSensorExpFunc);

    memset(pstSensorExpFunc, 0, sizeof(SENSOR_EXP_FUNC_S));

    pstSensorExpFunc->pfnSensorPowerUp  = CAMERA_PowerUp;
    pstSensorExpFunc->pfnSensorPowerDown = CAMERA_PowerDown;
    pstSensorExpFunc->pfnSensorDetect   = CAMERA_Detect;
    pstSensorExpFunc->pfnSensorInit     = CAMERA_Init;
    pstSensorExpFunc->pfnSensorStream   = CAMERA_Stream;
    pstSensorExpFunc->pfnSensorExit     = CAMERA_Exit;
    pstSensorExpFunc->pfnSensorSetImageMode   = CAMERA_SetImageMode;
    pstSensorExpFunc->pfnSensorEnumSnstype   = CAMERA_EnumSnstype;

    return EI_SUCCESS;
}

/****************************************************************************
 * callback structure                                                       *
 ****************************************************************************/

static EI_S32 CAMERA_CtxInit(VISS_DEV dev)
{
    SNS_STATE_S *pastSnsStateCtx = EI_NULL;

    SNS_GET_CTX(dev, pastSnsStateCtx);

    CAMERA_CHECK_POINTER(pastSnsStateCtx);

    memset(pastSnsStateCtx, 0, sizeof(SNS_STATE_S));

    pastSnsStateCtx->pstPowerUpAct      = s_stPowerUpAct;
    pastSnsStateCtx->pstPowerDownAct    = s_sPowerDownAct;
    pastSnsStateCtx->u8PwrUpActs        = ARRAY_SIZE(s_stPowerUpAct);
    pastSnsStateCtx->u8PwrDnActs        = ARRAY_SIZE(s_sPowerDownAct);

    return EI_SUCCESS;
}

static EI_VOID CAMERA_CtxExit(VISS_DEV dev)
{
    return ;
}

static EI_S32 CAMERA_RegisterVissCallback(VISS_DEV dev, SNS_TYPE_E enType)
{
    EI_S32 s32Ret;
    SENSOR_S stSns = {0};
    EI_U32 i;
    SNS_STATE_S *pstSnsState = EI_NULL;

    s32Ret = CAMERA_CtxInit(dev);
    if (EI_SUCCESS != s32Ret) {
        return EI_FAILURE;
    }

    SNS_GET_CTX(dev, pstSnsState);

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsState->pstSnsAttr = &s_astSnsAttr[i];
            break;
        }
    }

    pstSnsState->enSnsType = enType;
    pstSnsState->Dev = dev;

    if (i >= ARRAY_SIZE(s_astSnsAttr)) {
        PRT_VISS_ERR("%s does not support this chn configuration", SNS_NAME);
        return EI_FAILURE;
    }

    s32Ret = CAMERA_I2cInit(dev);
    if (EI_SUCCESS != s32Ret) {
        return EI_FAILURE;
    }

    stSns.stSnsAttrInfo.eSensorId = SNS_ID;
    stSns.stSnsAttrInfo.enDevType = DEV_TYPE;
    stSns.stSnsAttrInfo.pstSns = pstSnsState;

    s32Ret  = CAMERA_InitSensorExpFunction(&stSns.stSnsAttrInfo.stSnsExp);
    s32Ret |= VISS_SensorRegCallBack(dev, &stSns);
    if (EI_SUCCESS != s32Ret) {
        PRT_VISS_ERR("%s sensor register callback function failed!\n", SNS_NAME);
        return s32Ret;
    }

    s32Ret = CAMERA_OpenI2c(pstSnsState);
    CAMERA_CHECK_SUCCESS(s32Ret);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_UnregisterVissCallback(VISS_DEV dev)
{
    EI_S32 s32Ret;
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);

    s32Ret = CAMERA_ExitI2c(pstSnsState);
    CAMERA_CHECK_SUCCESS(s32Ret);

    s32Ret = VISS_SensorUnRegCallBack(dev, SNS_ID);
    if (EI_SUCCESS != s32Ret) {
        PRT_VISS_ERR("%s sensor unregister callback function failed!\n", SNS_NAME);
        return s32Ret;
    }

    CAMERA_CtxExit(dev);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_GetVissDevAttrBySns(SNS_TYPE_E enType,
    VISS_DEV_ATTR_S *pstVissDevAttr)
{
    EI_U32 i;
    const SNS_TYPE_ATTR_S *pstSnsType;

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsType = &s_astSnsAttr[i];
            pstVissDevAttr->stSize          = pstSnsType->stSize;
            pstVissDevAttr->enWorkMode      = pstSnsType->enWorkMode;
            pstVissDevAttr->mClock          = pstSnsType->u32Mclock;
            pstVissDevAttr->enPixelFormat   = pstSnsType->enPixelFormat;
            pstVissDevAttr->enWdrMode       = pstSnsType->enWdrMode;
            pstVissDevAttr->enIspWdrMode    = pstSnsType->enIspWdrMode;
            pstVissDevAttr->enRgbSeq        = pstSnsType->enRgbSeq;
            pstVissDevAttr->u32ModuleClk    = pstSnsType->u32ModuleClk;
            pstVissDevAttr->u32Fps          = pstSnsType->u32FrameRate;
            pstVissDevAttr->u32IspClk       = pstSnsType->u32IspClk;
            pstVissDevAttr->u32IppuClk      = pstSnsType->u32IppuClk;
            pstVissDevAttr->pcSnsName       = SNS_NAME;
            pstVissDevAttr->stDevCfg        = pstSnsType->stDevCfg;
            return EI_SUCCESS;
        }
    }

    PRT_VISS_ERR("%s does not support this dev configuration", SNS_NAME);

    return EI_FAILURE;
}

static EI_S32 CAMERA_GetVissChnAttrBySns(SNS_TYPE_E enType,
    VISS_CHN_ATTR_S *pstVissChnAttr)
{
    EI_U32 i;
    const SNS_TYPE_ATTR_S *pstSnsType;

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsType = &s_astSnsAttr[i];
            pstVissChnAttr->stSize           = pstSnsType->stSize;
            pstVissChnAttr->enPixelFormat    = pstSnsType->enPixelFormat;
            pstVissChnAttr->stFrameRate.s32SrcFrameRate      = pstSnsType->u32FrameRate;
            return EI_SUCCESS;
        }
    }

    PRT_VISS_ERR("%s does not support this chn configuration", SNS_NAME);

    return EI_FAILURE;

}

CAMERA_OBJ_S stCameraOv2710Obj = {
    .pfnRegisterVissCallback    = CAMERA_RegisterVissCallback,
    .pfnUnRegisterVissCallback  = CAMERA_UnregisterVissCallback,
    .pfnRegisterIspCallback     = EI_NULL,
    .pfnUnRegisterIspCallback   = EI_NULL,
    .pfnGetVissDevAttrBySns     = CAMERA_GetVissDevAttrBySns,
    .pfnGetVissChnAttrBySns     = CAMERA_GetVissChnAttrBySns,
};

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

